<?php

namespace App\Http\Controllers;

use App\Exports\ArchiveVolume10Export;
use App\Exports\ArchiveVolumeExport;
use App\Imports\ArchiveManageVolumeImport;
use App\Models\ArchiveManageVolume;
use App\Models\Menu;
use App\Models\PartCompany;
use App\Models\Project;
use App\Services\ArchiveManageService;
use App\Services\AttachmentService;
use App\Services\CommonService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Maatwebsite\Excel\Facades\Excel;

class ArchiveManageVolumeController extends Controller
{
    public $archiveManageService;

    public function __construct(ArchiveManageService $archiveManageService)
    {
        parent::__construct();
        $this->archiveManageService = $archiveManageService;
    }

    /**
     * 获取参见单位列表
     */
    public function getPartCompanyList(Request $request): JsonResponse
    {
        $projectId  = $request->input('project_id');
        $ptType     = $request->input('pt_type', 0);
        $volumeType = $request->input('volume_type', 0);
        $perPage    = $request->input('per_page') ?: 20;

        $list = PartCompany::query()
            ->when($ptType, function ($query) use ($ptType) {
                return $query->where('type', $ptType);
            })
            ->select('id', 'title', 'type', 'contract_num')
            ->where('project_id', $projectId)
            ->orderBy('type')
            ->orderBy('id') //加一个唯一字段，防止分页丢失数据
            ->paginate($perPage);

        $list = $list->toArray();
        foreach ($list['data'] as &$val) {
            $val['volume_id'] = 0;
            $val['file_url']  = '';
            $info = ArchiveManageVolume::query()->where('part_company_id', $val['id'])->where('type', $volumeType)->first();
            if ($info) {
                $val['volume_id'] = $info->id;
                $val['file_url']  = $info->file_url;
            }
            $val['type_text'] = PartCompany::TYPE[$val['type']];
        }

        return $this->success($list);
    }

    /**
     * 新增数据
     *
     * @param Request $request
     * @return JsonResponse
     * @author: lxk
     * @date: 2024-12-29 9:08
     */
    public function addData(Request $request): JsonResponse
    {
        $params    = $request->input();
        $thisQuery = ArchiveManageVolume::query()
            ->where('type', $params['type'])
            ->where('project_id', $params['project_id']);
        if (request()->filled('selectIds')) { //视为插入一行，插入到被选行的上方，然后更新当前案卷下的卷内序号
            $selectIds = to_array($params['selectIds']); //id 为一个或多个，
            $serialNo  = ArchiveManageVolume::query()->whereIn('id', $selectIds)->where('type', $params['type'])->min('serial_no'); //获取选择里面的最小值
            $thisQuery->where('serial_no', '>=', $serialNo)->increment('serial_no'); //把序号大于当前的那些数据增加
        } else { //获取本案卷最大的序号再 + 1
            $info     = $thisQuery->latest('serial_no')->select('serial_no')->first();
            $serialNo = $info ? $info->serial_no + 1 : 1;
        }
        $batchData['project_id']  = $params['project_id'];
        $batchData['serial_no']   = $serialNo;
        $batchData['file_number'] = '这是默认文件编号';
        $batchData['type']        = $params['type'];
        $batchData['file_name']   = '';
        $batchData['remark']      = '';
        $batchData['created_at']  = now();
        $batchData['updated_at']  = now();
        ArchiveManageVolume::query()->insert($batchData);

        $msg = request()->filled('selectIds') ? "成功插入1条数据" : "成功新增1条数据";

        return $this->success('', $msg);
    }

    /**
     * 修改数据
     *
     * @param Request $request
     * @return JsonResponse
     * @author: lxk
     * @date: 2024-12-29 9:09
     */
    public function updateData(Request $request): JsonResponse
    {
        $params = $request->input();

        $archiveManageVolume              = ArchiveManageVolume::query()->find($params['id']);
        $archiveManageVolume->serial_no   = $params['serial_no'];
        $archiveManageVolume->file_number = $params['file_number'];
        $archiveManageVolume->file_name   = $params['file_name'];
        $archiveManageVolume->remark      = $params['remark'];
        $archiveManageVolume->save();

        return $this->success('', '修改成功！');
    }

    /**
     * 获取业务规范类列表
     *
     * @param Request $request
     * @return JsonResponse
     * @author: lxk
     * @date: 2024-12-29 9:09
     */
    public function getSpecificationList(Request $request): JsonResponse
    {
        $projectId = $request->input('project_id');
        $type      = $request->input('type');
        $keyword   = $request->input('keyword');
        $perPage   = $request->input('per_page') ?: 20;
        $list      = ArchiveManageVolume::query()
            ->where('project_id', $projectId)
            ->where('type', $type)
            ->when($keyword, function ($query) use ($keyword) {
                $likeKeyword = "%{$keyword}%";
                return $query->where('file_number', 'like', $likeKeyword)->orWhere('file_name', 'like', $likeKeyword);
            })
            ->orderBy('serial_no')
            ->select('id', 'serial_no', 'file_number', 'file_name', 'remark', 'type', 'file_url')
            ->paginate($perPage);

        $data = $list->isNotEmpty() ? $list->toArray() : [];

        return $this->success($data);
    }

    /**
     * 导入业务规范等目录
     *
     * @param Request $request
     * @return JsonResponse
     * @throws \App\Exceptions\ApiException
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     * @author: lxk
     * @date: 2024-12-29 9:07
     */
    public function import(Request $request): JsonResponse
    {
        $projectId = $request->input('project_id');
        $type      = $request->input('type');

        CommonService::isFileValid($request); //验证文件是否合法
        $importCountKey = get_rand_str('import_archive_manage_volumes_count');
        redis()->setex($importCountKey, 600, 0); //用时最大10分钟
        Excel::import(new ArchiveManageVolumeImport($importCountKey, $projectId, $type), $request->file('file'));
        $count = redis()->get($importCountKey) ?: 0;

        CommonService::addActionLog("导入业务规范", "【{$count}】条数据");

        return $this->success('', "成功导入【{$count}】条数据");
    }

    /**
     * 导出数据
     *
     * @param Request $request
     * @return JsonResponse
     * @author: lxk
     * @date: 2024-12-29 9:07
     */
    public function export(Request $request): JsonResponse
    {
        $projectId   = $request->input('project_id');
        $type        = $request->input('type');
        $keyword     = $request->input('keyword');
        $selectIds   = $request->input('selectIds');
        $typeText    = ArchiveManageVolume::getTypeText($type);
        $projectName = Project::query()->where('id', $projectId)->value('title');
        try {
            $fileName = get_valid_path("{$projectName}_{$typeText}_". date('His') . '.xlsx');
            $filePath = "public/excels/$fileName" ;
            if ($type == 10) {
                (new ArchiveVolume10Export($projectId, $type, $keyword, $selectIds))->store($filePath);
            } else {
                (new ArchiveVolumeExport($projectId, $type, $keyword, $selectIds))->store($filePath);
            }
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
        $filePath    = str_replace('public', 'storage', $filePath);
        $downloadUrl = config('site.domain') . $filePath;
        $fileInfo    = pathinfo($downloadUrl);
        $data        = [
            'basename'     => $fileInfo['basename'],
            'download_url' => $downloadUrl
        ];
        CommonService::addActionLog("导出{$typeText}");

        return $this->success($data);
    }

    /**
     * 批量软删除，ids可以是以","逗号分割的字符串，也可以是数组形式
     *
     * @param Request $request
     * @return JsonResponse
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     * @author: lxk
     * @date: 2024-12-29 9:07
     */
    public function destroyMore(Request $request): JsonResponse
    {
        $projectId = $request->input('project_id');
        $type      = $request->input('type');
        $ids       = $request->input('ids');
        if (!ArchiveManageVolume::destroy(to_array($ids))) {
            return $this->error('删除失败！');
        };
        $redisKey = get_rand_str('del_archive_volume');
        redis()->set($redisKey, 0); //定义个临时变量
        ArchiveManageVolume::query()
            ->where('project_id', $projectId)
            ->where('type', $type)
            ->select('id', 'serial_no')
            ->orderBy('serial_no')
            ->orderBy('id')
            ->chunk(100, function ($list) use ($redisKey) {
                foreach ($list as $val) {
                    redis()->incrby($redisKey, 1); //加1
                    $serialNo = redis()->get($redisKey); //获取增加后的值
                    ArchiveManageVolume::query()->where('id', $val->id)->update(['serial_no' => $serialNo]);
                }
            });
        redis()->del($redisKey); //用完删除
        $typeText = ArchiveManageVolume::getTypeText($type);
        CommonService::addActionLog("删除{$typeText}", "数据ID:{$ids}");

        return $this->success('', '删除成功！');
    }

    /**
     * 上传PDF  archive_manage_volume
     *
     * @param Request $request
     * @return JsonResponse
     * @throws \OSS\Http\RequestCore_Exception
     * @author: lxk
     * @date: 2024-12-27 13:22
     */
    public function uploadFile(Request $request): JsonResponse
    {
        $dataId        = $request->input('data_id', 0);
        $projectId     = $request->input('project_id', 0);
        $partCompanyId = $request->input('part_company_id', 0);
        $type          = $request->input('type');
        $file          = $request->file('file');
        if (empty($type)) {
            return $this->error('参数type不能为空！');
        }
        $uploadResult = (new AttachmentService())->upload($file, 'oss', $partCompanyId);
        if ($dataId && is_numeric($dataId)) {
            ArchiveManageVolume::query()->where('id', $dataId)->update([
                'file_url' => $uploadResult['file'],
            ]);
            return $this->success('', '上传成功！');
        }
        else {
            ArchiveManageVolume::query()->insert([
                'project_id'      => $projectId,
                'part_company_id' => $partCompanyId,
                'type'            => $type,
                'file_url'        => $uploadResult['file'],
            ]);
        }
        return $this->success('', '上传成功！');
    }

}
